package com.intellif.mozping.concurrentutil.forkjiondemo;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;


/**
 * @author by mozping
 * @Classname FileCounter
 * @Description TODO
 * @Date 2019/2/28 15:31
 */

/**
 * 查找文件夹下有多少个文件
 */
public class FileCounter extends RecursiveTask<Long> {

    private File target;

    public FileCounter(File target) {
        this.target = target;
    }

    /**
     * 主方法
     *
     * @param filePath
     * @return
     */
    public static Long getFileNumber(String filePath) {
        File f = new File(filePath);
        FileCounter fileCounter = new FileCounter(f);
        ForkJoinPool pool = new ForkJoinPool();
        Long result = pool.invoke(fileCounter);
        return result;
    }

    @Override
    protected Long compute() {
        Pair p = computeD();
        if (!p.fileList.isEmpty()) {
            List<FileCounter> fileCounters = p.fileList.stream().map(FileCounter::new)
                    .collect(Collectors.toList());
            invokeAll(fileCounters);    //而非每一个  invoke()
            return p.num + fileCounters.stream().mapToLong(FileCounter::join).sum();  //这里划分为更小的任务？还有更好的方法吗
        }
        return p.num;
    }

    private Pair computeD() {
        Pair p = new Pair();
        File[] files = target.listFiles();
        if (files == null || files.length == 0) {
            return p;
        }
        int counter = 0;

        for (File it : files) {
            if (it.isFile()) {
                counter++;
            } else {
                p.fileList.add(it);
            }
        }
        p.num = (long) counter;
        return p;
    }


    public static void main(String[] args) {
        long begin = System.currentTimeMillis();
        // System.out.println(getFileNumber("D:\\mavenrepository\\repository"));
        System.out.println(getFileNumber("X:\\"));
        System.out.println("耗时：" + (System.currentTimeMillis() - begin));
    }

    static class Pair {
        Long num = 0L;
        List<File> fileList = new ArrayList<>();
    }
}